﻿using System;
using System.Collections.Generic;
using System.Text;

namespace NeuralNetwork
{
    public class SinglePerceptron
    {
        // Khao báo các thành phần của lớp SinglePerceptron
        private float[] myX = new float[16];  // Thành phần vector đầu vào
        private float[] myW = new float[16] {0.1F, 0.1F, 0.1F, 0.1F, 0.1F, 0.1F, 0.1F, 0.1F, 0.1F ,0.1F,
                                              0.1F, -0.1F, 0.1F,- 0.1F, -0.1F, -0.1F}; // Thành phần vector trọng số
        private const float myD = 0; // Thành phần đầu ra mong muốn
        private float myY; // Thành phần đầu ra chạy qua mạng
        private float myUy; // Hệ số học trong mạng

        // Hàm khởi dựng của lớp SinglePerceptron gồm các thành phần X và Hệ số học 
        public SinglePerceptron(float[] X, float Uy)
        {
            this.myX = X;
            this.myUy = Uy;
        }

        // Hàm khởi dùng của lớp SinglePerceptron gồm các thành phần X, trọng số W, Hệ số học 
        public SinglePerceptron(float[] X, float[] W, float Uy)
        {
            this.myX = X;
            this.myW = W;
            this.myUy = Uy;            
        }
        // Hàm kích hoạt sign
        public static float signmoid(double Net)
        {
            if (Net > 0) return 1;
            else return -1;
            
        }

        // Hàm để mạng học
        public void Learning_Network()
        {
            double net = 0.0F;
            float J = 0.0F;
            const float epsilon = 0.0001F;
            int step = 0;
            do
            {
                // Lan truyền thuận
                for (int i = 0; i <= myX.Length - 1; i++)
                {
                    net += myX[i] * myW[i];
                }
                myY = (float)net;
                
                // Lan truyền ngược
                for (int i = 0; i <= myW.Length - 1; i++)
                {
                    myW[i] += myUy * (myD - myY)*myX[i];
                }

                // Tinh lai dau ra Y
                net = 0.0F;
                for (int i = 0; i <= myX.Length - 1; i++)
                {
                    net += myX[i] * myW[i]; 
                }
                myY = (float)net;
                // Tính J
                J = ((myD - myY) * (myD - myY)) / 2;
                step++;
            } while ((J >= epsilon)&&(step <= 1000));
        }

        // Ham thuoc tinh W
        public float[] W
        {
            get
            {
                return myW;
            }
            set
            {
                W = value;
            }
        }

        // Hàm thuộc tính Y
        public float Y
        {
            get
            {
                return myY;
            }
            set
            {
                Y = value;
            }
        }
    }
}
